﻿using System;
using System.ComponentModel;
using System.Diagnostics;

using ExchangeRateService.Helpers;

namespace ExchangeRateService.Model
{
	/// <summary>
	/// Object represents a currency supported by http://fx.sauder.ubc.ca/supplement.html.
	/// </summary>
	public class Currency : IDataErrorInfo
	{
		#region Creation

		public static Currency CreateNewCurrency()
		{
			return new Currency();
		}

		public static Currency CreateCurrency(
			String code,
			String name,
			Double usd,
			Double cad,
			Double eur,
			Double gbp)
		{
			return new Currency
			{
				Code = code,
				Name = name,
				USDRate = usd,
				CADRate = cad,
				EURRate = eur,
				GBPRate = gbp
			};
		}

		protected Currency()
		{
		}

		#endregion // Creation

		#region Properties

		/// <summary>
		/// Gets/sets the currency's code. Eg: VND
		/// </summary>
		public String Code { get; set; }

		/// <summary>
		/// Gets/sets the currency's name. Eg: Vietnamese Dong
		/// </summary>
		public String Name { get; set; }
		
		/// <summary>
		/// Gets/sets the United States Dollar rate.
		/// </summary>
		public Double USDRate { get; set; }
		
		/// <summary>
		/// Gets/sets the Canada Dollar rate.
		/// </summary>
		public Double CADRate { get; set; }
		
		/// <summary>
		/// Gets/sets the Euro rate.
		/// </summary>
		public Double EURRate { get; set; }
		
		/// <summary>
		/// Gets/sets the Great Britain Pound rate.
		/// </summary>
		public Double GBPRate { get; set; }

		#endregion // State Properties
		
		#region Object's Overriden

		public override int GetHashCode()
		{
			int hashCode = 0;
			
			unchecked
			{
				if (null != Code)
					hashCode += 1000000001 * Code.GetHashCode();

				if (null != Name)
					hashCode += 1000000002 * Name.GetHashCode();

				hashCode += 1000000003 * USDRate.GetHashCode();
				hashCode += 1000000004 * CADRate.GetHashCode();
				hashCode += 1000000005 * EURRate.GetHashCode();
				hashCode += 1000000006 * GBPRate.GetHashCode();
			}
			
			return hashCode;
		}
		
		public override bool Equals(object obj)
		{
			Currency other = obj as Currency;
			if (null == other)
				return false;
			
			return Code == other.Code;
		}

		public override string ToString()
		{
			return Code;
		}

		#endregion
		
		#region IDataErrorInfo Members

        string IDataErrorInfo.Error { get { return String.Empty; } }

        string IDataErrorInfo.this[string propertyName]
        {
            get { return this.GetValidationError(propertyName); }
        }

        #endregion // IDataErrorInfo Members

        #region Validation

        /// <summary>
        /// Returns true if this object has no validation errors.
        /// </summary>
        public bool IsValid
        {
            get
            {
                foreach (string property in Validated_Properties)
                    if (GetValidationError(property) != null)
                        return false;

                return true;
            }
        }

        static readonly string[] Validated_Properties = 
        { 
            "Code", 
            "Name"
        };

        string GetValidationError(string propertyName)
        {
            if (Array.IndexOf(Validated_Properties, propertyName) < 0)
                return null;

            string error = null;

            switch (propertyName)
            {
                case "Code":
                    error = this.ValidateCode();
                    break;

                case "Name":
                    error = this.ValidateName();
                    break;

                default:
                    Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                    break;
            }

            return error;
        }

        string ValidateCode()
        {
        	String validation = String.Empty;
        	
            if (RegexUtils.IsStringMissing(Code))
            {
            	validation = String.Format(Properties.StringResource.STRINGTYPE_VALIDATION, Validated_Properties[0]);
            }
            
            return validation;
        }
        
        string ValidateName()
        {
        	String validation = String.Empty;
        	
            if (RegexUtils.IsStringMissing(Name))
            {
            	validation = String.Format(Properties.StringResource.STRINGTYPE_VALIDATION, Validated_Properties[1]);
            }
            
            return validation;
        }

        #endregion // Validation
	}
}
